/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.global;

import java.util.Collection;

import org.zhiqim.kernel.config.Config;
import org.zhiqim.kernel.config.Group;
import org.zhiqim.kernel.config.Item;
import org.zhiqim.kernel.constants.ZhiqimConstants;
import org.zhiqim.kernel.model.maps.LinkedMapSV;
import org.zhiqim.kernel.model.maps.MapSV;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Longs;
import org.zhiqim.kernel.util.Validates;

/**
 * 全局配置管理器
 *
 * @version v8.0.1 @author zgzou 2022年2月12日 新建与整理
 */
public class Conf implements ZhiqimConstants
{
    private final MapSV<Config> configMap = new LinkedMapSV<>();
    private final MapSV<Group> groupMap = new LinkedMapSV<>();

    /** 获取配置信息 */
    public Config config(String name)
    {
        return configMap.get(name);
    }
    
    /** 获取配置组信息 */
    public Group group(String id)
    {
        return groupMap.get(id);
    }
    
    /** 获取配置项 */
    public Item item(String id, String key)
    {
        Group group = groupMap.get(id);
        return (group == null)?null:group.item(key);
    }
    
    /** 获取配置组列表 */
    public Collection<Group> list()
    {
        return groupMap.values();
    }
    
    /********************************************************************************************/
    //配置文件设置和获取等
    /********************************************************************************************/

    /** 设置配置信息，可能存在相同的配置名称或配置组号，有则返回，无返回null表示成功 */
    public String add(Config config)
    {
        if (configMap.containsKey(config.getName()))
            return config.getName();
        
        configMap.put(config.getName(), config);
        for (Group group : config.getGroupList())
        {
            if (groupMap.containsKey(group.getId()))
                return group.getId();
            
            groupMap.put(group.getId(), group);
        }
        return null;
    }
    
    /** 设置配置信息，仅一个配置组作为配置的情况 */
    public void addGroup(Group group)
    {
        String groupId = group.getId();
        
        Asserts.as(Validates.isNotEmpty(groupId)?null:"Group未配置组编号不允许增加到全局配置中");
        Asserts.as(!configMap.containsKey(groupId)?null:"Group组编号[%s]作为配置名时有重复", groupId);
        Asserts.as(!groupMap.containsKey(groupId)?null:"Group组编号[%s]有重复", groupId);
        
        Config config = new Config(group.getId());
        config.addGroup(group);
        configMap.put(groupId, config);
        groupMap.put(groupId, group);
    }
    
    /** 删除配置信息，仅一个配置组作为配置的情况 */
    public void removeGroup(String groupId)
    {
        configMap.remove(groupId);
        groupMap.remove(groupId);
    }
    
    /** 保存配置信息 */
    public void save(String name) throws Exception
    {
        Config config = configMap.get(name);
        if (config == null)
            throw new Exception("未找到对应的配置信息");
        
        config.save();
    }
    
    /** 保存配置信息 */
    public void saveByGroup(String id) throws Exception
    {
        Group group = groupMap.get(id);
        if (group == null)
            throw new Exception("未找到对应的配置信息");
        
        Config config = configMap.get(group.getName());
        if (config == null)
            throw new Exception("未找到对应的配置信息");
        
        config.save();
    }
    
    /********************************************************************************************/
    //设置配置属性
    /********************************************************************************************/
    
    /** 设置配置值 */
    public void setValue(String id, String key, String value)
    {
        Group group = groupMap.get(id);
        if (group == null)
            return;
        
        Item item = group.item(key);
        if (item != null)
            item.setValue(value);
    }
    
    /** 设置配置整型 */
    public void setInt(String id, String key, int value)
    {
        setValue(id, key, String.valueOf(value));
    }
    
    /** 设置配置长整型 */
    public void setLong(String id, String key, long value)
    {
        setValue(id, key, String.valueOf(value));
    }
    
    /** 设置配置布尔型 */
    public void setBoolean(String id, String key, boolean value)
    {
        setValue(id, key, String.valueOf(value));
    }
    
    /********************************************************************************************/
    //判断和获取配置属性
    /********************************************************************************************/
    
    /** 判断是否有配置组 */
    public boolean hasGroup(String id)
    {
        return groupMap.containsKey(id);
    }
    
    /** 判断是否有配置项 */
    public boolean hasItem(String id, String key)
    {
        Group group = groupMap.get(id);
        return (group == null)?false:group.hasItem(key);
    }
    
    /** 获取配置字符串 */
    public String getString(String id, String key)
    {
        Group group = groupMap.get(id);
        return (group == null)?null:group.getString(key);
    }
    
    /** 获取配置字符串，如果为null，返回缺省值 */
    public String getString(String id, String key, String defaultValue)
    {
        Group group = groupMap.get(id);
        return (group == null)?defaultValue:group.getString(key, defaultValue);
    }
    
    /** 获取配置整型，如果为null，返回-1 */
    public int getInt(String id, String key)
    {
        String value = getString(id, key);
        return (value == null)?-1:Ints.toInt(value, -1);
    }
    
    /** 获取配置整型，如果为null，返回缺省值 */
    public int getInt(String id, String key, int defaultValue)
    {
        String value = getString(id, key);
        return (value == null)?defaultValue:Ints.toInt(value, defaultValue);
    }

    /** 获取配置长整型，如果为null，返回-1 */
    public long getLong(String id, String key)
    {
        String value = getString(id, key);
        return (value == null)?-1:Longs.toLong(value, -1);
    }
    
    /** 获取配置长整型，如果为null，返回缺省值 */
    public long getLong(String id, String key, long defaultValue)
    {
        String value = getString(id, key);
        return (value == null)?defaultValue:Longs.toLong(value, defaultValue);
    }
    
    /** 判断配置是否为真 */
    public boolean isTrue(String id, String key)
    {
        return "true".equalsIgnoreCase(getString(id, key));
    }
    
    /** 判断配置是否为真 */
    public boolean isTrue(String id, String key, boolean defaultValue)
    {
        String value = getString(id, key);
        return (value == null)?defaultValue:"true".equalsIgnoreCase(value);
    }
    
    /********************************************************************************************/
    //常用配置属性
    /********************************************************************************************/

    /** 获取系统引导名称 */
    public String getName()
    {
        return getString(Z_BOOT, Z_ITEM_NAME, Z_NAME_CN);
    }
    
    /** 获取系统引导版本 */
    public String getVersion()
    {
        return getString(Z_BOOT, Z_ITEM_VERSION, Z_VERSION);
    }
    
    /** 获取系统引导端口 */
    public int getPort()
    {
        return getInt(Z_BOOT, Z_ITEM_PORT);
    }
}
